package simple.flow.util;

import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 密码工具类
 *
 * @author lhd
 * @since 2025/4/7 15:31
 */

@Slf4j
public class PasswordUtil {

    private static final int SALT_LENGTH = 16;

    /**
     * 生成随机盐
     *
     * @param length 盐的长度
     * @return 盐值
     */
    public static String generateSalt(int length) {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[length];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }

    public static String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[SALT_LENGTH];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }


    /**
     * 加密密码
     *
     * @param password 密码
     * @param salt     盐值
     * @return 加密后的密码
     */
    public static String encrypt(String password, String salt) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] saltBytes = Base64.getDecoder().decode(salt);
            digest.update(saltBytes);
            byte[] encodedHash = digest.digest(password.getBytes(StandardCharsets.UTF_8));

            StringBuilder hexString = new StringBuilder(2 * encodedHash.length);
            for (byte b : encodedHash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            log.error("加密失败", e);
        }

        return null;
    }

    /**
     * 匹配密码
     *
     * @param inputPassword 输入的密码
     * @param storedHash    存储的hash值
     * @param storedSalt    存储的盐值
     * @return 是否匹配
     */
    public static boolean match(String inputPassword, String storedHash, String storedSalt) {
        // 判断为空的时候，直接返回false
        if (inputPassword == null || inputPassword.isEmpty()
                || storedHash == null || storedHash.isEmpty()
                || storedSalt == null || storedSalt.isEmpty()
        ) {
            return false;
        }

        // 进行加密
        String inputHash = encrypt(inputPassword, storedSalt);
        if (inputHash == null) {
            return false;
        }

        // 比较加密后的密码是否一致
        return inputHash.equals(storedHash);
    }

}
